/**
 * =====================================================================================
 *
 *    @file:  db_relation.c
 *
 *    @brief:  对一个关系数据库抽象接口实现，使用这些接口
 *					应该链接此文件。
 *
 *    @version:  1.0
 *    Created:  2010年04月08日 13时35分55秒
 *    Revision:  none
 *    Compiler:  gcc -Wall -Wextra db_table.c
 *
 *    @author:  easyeagel (LiuGuangBao), easyeagel@gmx.com
 *    Company:  简单C++ - www.easycpp.org
 *
 * =====================================================================================
 */

#include<stdlib.h>
#include<string.h>
#include<assert.h>

#include"opapi.hpp"
#include"cache.hpp"
#include"cache_vector.hpp"
#include"db_relation.hpp"
#include"db_implement.hpp"
#include"opmap.hpp"

void rlt_source_print(void* p)
{
	source_t* sc=(source_t*)(p);
	srlt_cache_print(sc->cache);
}

static void* srlt_db_find(source_t* sc, const char* name, db_type_t* type);

RLTcntor_t* rlt_create(const char* server, unsigned short port, unsigned long timeout)
{
	RLTcntor_t* ret=(RLTcntor_t*)malloc(sizeof(*ret));
	assert(ret);

	source_t* sc=(source_t*)malloc(sizeof(*sc));
	assert(sc);

	memset(ret, 0, sizeof(*ret));
	memset(sc, 0, sizeof(*sc));

	ret->server=str_dup(server);
	ret->port=port;
	ret->timeout=timeout;
	ret->source=sc;

	return ret;
}

int rlt_use_db(RLTcntor_t* cntor, const char* name)
{
	source_t* sc=(source_t*)cntor->source;
	int is_abc=(0==strncmp(name, "root", 4));
	if(!is_abc && sc->used_db_name==NULL)
	{
		return RLT_no;
	}

	char tname[RLT_max_path_length];
	if(is_abc)
	{
		strncpy(tname, name, RLT_max_path_length);
	} else {
		strncpy(tname, sc->used_db_name, RLT_max_path_length);
		strncat(tname, ".", RLT_max_path_length);
		strncat(tname, name, RLT_max_path_length);
	}

	void* db;
	db_type_t type=e_db_none;
	if(NULL==(db=srlt_db_find(sc, tname, &type)))
	{
		return RLT_no;
	}

	if(sc->used_db_name)
	{
		free((void*)sc->used_db_name);
	}

	sc->used_db_type=type;
	sc->used_db=db;
	sc->used_db_name=str_dup(tname);

	return RLT_yes;
}

int rlt_connect(RLTcntor_t* cntor)
{
	source_t* sc=(source_t*)cntor->source;
	if(sc->is_cnted)
	{
		return RLT_yes;
	}

	int ret=op_init(cntor->server, cntor->port, cntor->timeout);
	if(0!=ret)
	{
		return RLT_no;
	}

	sc->is_cnted=1;
	if(sc->use_cache)
	{
		const char** ps=dbop_get_plant(sc);
		srlt_cache_load(sc->cache, ps);
	}

	return RLT_yes;
}

int rlt_cache(RLTcntor_t* cntor)
{
	if(NULL==cntor->source)
	{
		return RLT_no;
	}

	source_t* sc=(source_t*)cntor->source;
	sc->use_cache=1;
	if(NULL!=sc->cache)
	{
		return RLT_yes;
	}

	cache_t* cac=(cache_t*)malloc(sizeof(*cac));
	assert(cac);

	sc->cache=cac;

	srlt_cache_init(cac);

	if(sc->is_cnted)
	{
		const char** ps=dbop_get_plant(sc);
		srlt_cache_load(cac, ps);
	}

	return RLT_yes;
}

void rlt_uncache(RLTcntor_t* cntor)
{
	source_t *sc=(source_t*)cntor->source;
	sc->use_cache=0;
}

int rlt_db_is_exist(RLTcntor_t* db, const char* db_name)
{
	db--, db++;
	db_name--, db_name++;
	return RLT_no;
}

int rlt_table_is_exist(RLTcntor_t* db, const char* table_name)
{
	db--, db++;
	table_name--, table_name++;
	return RLT_no;
}

int rlt_filed_is_exist(RLTcntor_t* db, const char* filed_name)
{
	db--, db++;
	filed_name--, filed_name++;
	return RLT_no;
}

/* ======================================================== */
/* 基本的本地函数 */

/** 
* @brief 通过全名找到数据库结点的指针
* 
* @param sc
* @param name
* @param type
* 
* @return 
*/
static void* srlt_db_find(source_t* sc, const char* name, db_type_t* type)
{
	sc++, sc--;
	name++, name--;
	type++, type--;
	return RLT_no;
}

